package com.code.statistics.services.impl;

import com.code.statistics.daos.CurrentDayGroupStatisticsMapper;
import com.code.statistics.managers.HttpManager;
import com.code.statistics.models.CurrentDayGroupStatistics;
import com.code.statistics.models.StatisticsGroup;
import com.code.statistics.services.CurrentDayGroupStatisticsService;
import com.code.statistics.services.InOutGroupService;
import com.code.statistics.services.StatisticsGroupService;
import com.code.statistics.utils.TimeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 当日群组统计实现类
 *
 * @author xiaoyaowang
 */
@Service
public class CurrentDayGroupStatisticsServiceImpl implements CurrentDayGroupStatisticsService {

    private static Logger logger = LoggerFactory.getLogger(CurrentDayGroupStatisticsServiceImpl.class);

    @Resource
    private StatisticsGroupService statisticsGroupService;

    @Resource
    private CurrentDayGroupStatisticsService currentDayGroupStatisticsService;

    @Resource
    private InOutGroupService inOutGroupService;

    @Resource
    private HttpManager httpManager;

    @Resource
    private CurrentDayGroupStatisticsMapper currentDayGroupStatisticsMapper;

    @Override
    public int statisticsGroupMessagesOrGroupNewMembers(String groupUrl, int version, int newMembers, int type) {
        Integer groupId = statisticsGroupService.getIdByGroupUrl(groupUrl);
        if (null == groupId) {
            return 0;
        }
        String currentDate = TimeUtil.nowDateWithYmd();
        Integer currentDayGroupStatisticsId = currentDayGroupStatisticsMapper.whetherExistCurrentDayGroupStatistics(groupId, currentDate);
        logger.info("groupId:{} currentDate:{}", groupId, currentDate);
        if (null == currentDayGroupStatisticsId) {
            CurrentDayGroupStatistics currentDayGroupStatistics = new CurrentDayGroupStatistics();
            currentDayGroupStatistics.setGroupId(groupId);
            currentDayGroupStatistics.setCurrentDayMessages(1);
            currentDayGroupStatistics.setCurrentDayNewMembers(0);
            currentDayGroupStatistics.setCurrentDayDate(currentDate);
            currentDayGroupStatistics.setVersion(0);
            currentDayGroupStatistics.setDeleted(0);
            currentDayGroupStatistics.setCreatedAt(TimeUtil.localDateTimeTransferDate());
            currentDayGroupStatistics.setUpdatedAt(TimeUtil.localDateTimeTransferDate());
            return currentDayGroupStatisticsMapper.insert(currentDayGroupStatistics);
        } else {
            if (type == 1) {
                return currentDayGroupStatisticsMapper.increaseMessages(currentDayGroupStatisticsId, version, new Date());
            } else {
                return currentDayGroupStatisticsMapper.increaseNewMembers(currentDayGroupStatisticsId, newMembers, version, new Date());
            }
        }
    }

    @Override
    public int getVersionByGroupUrl(String groupUrl) {
        Integer groupId = statisticsGroupService.getIdByGroupUrl(groupUrl);
        if (null == groupId) {
            return 0;
        }
        String currentDate = TimeUtil.nowDateWithYmd();
        Integer version = currentDayGroupStatisticsMapper.getVersionByGroupIdAndCurrentDate(groupId, currentDate);
        if (null == version) {
            return 0;
        }
        return version;
    }

    @Override
    public void synCurrentDayJoinGroupMembers() {
        // 获取所有组
        List<StatisticsGroup> statisticsGroupList = statisticsGroupService.getStatisticsGroupList();
        if (CollectionUtils.isEmpty(statisticsGroupList)) {
            return;
        }
        Integer groupId;
        String groupUrl;
        Optional<Integer> totalIncreaseMembersOpt;
        Integer totalIncreaseMembers;
        CurrentDayGroupStatistics currentDayGroupStatistics;
        int size = statisticsGroupList.size();
        List<CurrentDayGroupStatistics> currentDayGroupStatisticList = new ArrayList<>(size);
        Integer currentDayGroupStatisticsId;
        List<Integer> increaseMembers;
        String yesterday = TimeUtil.getYesterdayByFormat(TimeUtil.Y_M_D);
        for (StatisticsGroup statisticsGroup : statisticsGroupList) {
            totalIncreaseMembers = 0;
            groupUrl = statisticsGroup.getGroupUrl();
            increaseMembers = inOutGroupService.getMembersByGroupUrlAndInOutTypeInCurrentDay(groupUrl, 1, yesterday);
            if (CollectionUtils.isEmpty(increaseMembers)) {
                continue;
            }
            totalIncreaseMembersOpt = increaseMembers.stream().reduce(Integer::sum);
            if (totalIncreaseMembersOpt.isPresent()) {
                totalIncreaseMembers = totalIncreaseMembersOpt.get();
            }
            logger.info("currentDay:{}, totalIncreaseMembers :{}", yesterday, totalIncreaseMembers);
            groupId = statisticsGroup.getId();
            currentDayGroupStatistics = new CurrentDayGroupStatistics();
            currentDayGroupStatisticsId = currentDayGroupStatisticsMapper.whetherExistCurrentDayGroupStatistics(groupId, yesterday);
            if (null == currentDayGroupStatisticsId) {
                currentDayGroupStatistics.setIsIncrease(1);
            } else {
                currentDayGroupStatistics.setIsIncrease(0);
                currentDayGroupStatistics.setId(currentDayGroupStatisticsId);
            }
            currentDayGroupStatistics.setCurrentDayMembers(httpManager.getNewChatMemberCount(statisticsGroup.getGroupChatId()));
            currentDayGroupStatistics.setCurrentDayDate(yesterday);
            currentDayGroupStatistics.setGroupId(groupId);
            currentDayGroupStatistics.setCurrentDayNewMembers(totalIncreaseMembers);
            currentDayGroupStatisticList.add(currentDayGroupStatistics);
        }
        currentDayGroupStatisticsService.insertCurrentDayGroupStatisticListOrPatchUpdateCurrentDayGroupStatisticList(currentDayGroupStatisticList);
    }

    @Transactional(transactionManager = "testTransactionManager", rollbackFor = Exception.class)
    @Override
    public int insertCurrentDayGroupStatisticListOrPatchUpdateCurrentDayGroupStatisticList(List<CurrentDayGroupStatistics> currentDayGroupStatisticList) {
        int count = 0;
        if (!CollectionUtils.isEmpty(currentDayGroupStatisticList)) {
            List<CurrentDayGroupStatistics> addCurrentDayGroupStatistics = currentDayGroupStatisticList.stream()
                    .filter(currentDayGroupStatistics -> currentDayGroupStatistics.getIsIncrease() == 1).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(addCurrentDayGroupStatistics)) {
                addCurrentDayGroupStatistics.forEach(currentDayGroupStatistics -> {
                    currentDayGroupStatistics.setCurrentDayMessages(0);
                    currentDayGroupStatistics.setVersion(0);
                    currentDayGroupStatistics.setDeleted(0);
                    currentDayGroupStatistics.setCreatedAt(TimeUtil.localDateTimeTransferDate());
                    currentDayGroupStatistics.setUpdatedAt(TimeUtil.localDateTimeTransferDate());
                });
                count += currentDayGroupStatisticsMapper.insertList(addCurrentDayGroupStatistics);
            }
            List<CurrentDayGroupStatistics> updateCurrentDayGroupStatistics = currentDayGroupStatisticList.stream()
                    .filter(currentDayGroupStatistics -> currentDayGroupStatistics.getIsIncrease() != 1).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(updateCurrentDayGroupStatistics)) {
                updateCurrentDayGroupStatistics.forEach(currentDayGroupStatistics -> {
                    currentDayGroupStatistics.setUpdatedAt(new Date());
                });
                count += currentDayGroupStatisticsMapper.patchUpdateNewMembers(updateCurrentDayGroupStatistics);
            }
            if (count > 0) {
                String yesterday = currentDayGroupStatisticList.get(0).getCurrentDayDate();
                inOutGroupService.deleteInOutGroupByCurrentDay(yesterday);
            }
        }
        return count;
    }
}
